﻿import arkadium.SoundClip;
import arkadium.EventManager;
import arkadium.SharedObjectManager;
import mx.utils.Delegate;

dynamic class arkadium.SoundManager
{
	private var _aSoundList:Array;
	private var _aExternalSoundList:Array;
	private var _aExternalMusicList:Array;
	
	private var _bSoundOn:Boolean
	private var _bMusicOn:Boolean
	
	private var _mcAudioContainer:MovieClip
	private var _mcSoundContainer:MovieClip
	private var _mcMusicContainer:MovieClip
	
	private var _snGlobalAudio:Sound
	private var _snGlobalSound:Sound
	private var _snGlobalMusic:Sound
	
	public var _cEventManager:EventManager;
	public var _cSharedObjectManager:SharedObjectManager;

	public function SoundManager(){
		_aSoundList = new Array();
		_aExternalSoundList = new Array();
		_aExternalMusicList = new Array();
	}

	function onInitialize( mcStage:MovieClip, cEventManager:EventManager, cSharedObjectManager:SharedObjectManager){
		_cSharedObjectManager = cSharedObjectManager;
		_cEventManager = cEventManager;
		
		//we will have one audio controler movieclip.  This will control the total sound and total mute functions
		//inside this will be two clips, sound, and music which will allow us to tune these volumes seperately
		//inside each of these clips will be individual clips for each sound
		if ( _mcAudioContainer == undefined ) {
			_mcAudioContainer = mcStage.createEmptyMovieClip( "_smcAudioContainer", mcStage.getNextHighestDepth() ); 
			_mcSoundContainer = mcStage._smcAudioContainer.createEmptyMovieClip( "_smcSoundContainer", mcStage._smcAudioContainer.getNextHighestDepth() ); 
			_mcMusicContainer = mcStage._smcAudioContainer.createEmptyMovieClip( "_smcMusicContainer", mcStage._smcAudioContainer.getNextHighestDepth() ); 
		
			_snGlobalAudio = new Sound(_mcAudioContainer);
			_snGlobalSound = new Sound(_mcSoundContainer);
			_snGlobalMusic = new Sound(_mcMusicContainer);
		}
	
		//under most conditions we assume that the sounds are on.
		_bMusicOn = true;
		_bSoundOn = true;
		
		//however this will look to the shared object to see if the sounds have been turned off last time the game was played
		//This means that the shared object needs to be loaded in main before the sound manager
		
		var bSoundOn:Boolean = _cSharedObjectManager.loadData("bSoundOn")
		if( bSoundOn == undefined) _cSharedObjectManager.saveData("bSoundOn",true);
		else if(bSoundOn == false){
			toggleSoundOn();
			
		}
		var bMusicOn:Boolean = _cSharedObjectManager.loadData("bMusicOn")
		if(bMusicOn  == undefined) _cSharedObjectManager.saveData("bMusicOn",true);
		else if(bMusicOn == false){
			toggleMusicOn()
		}
	}
	
	function attachExternalSound( sLinkageID:String, sURL:String, bMusic:Boolean , nVolume):Number
	{
		// Let's check to see if the sound we're trying to attach has already been attached and
		// if so, we'll just return the existing sound ID.
		var nExistingSoundID:Number = getSoundID( sLinkageID );
		if ( nExistingSoundID != null ) 
		{
			return nExistingSoundID;
		}
		var pSoundClip:SoundClip = new SoundClip(this);
	
		// Since we didn't find the sound to exist already - we'll create it
		
		var mcSoundTarget:MovieClip // Damian: Declaration moved here.
		
		if(bMusic){
			mcSoundTarget = _mcMusicContainer.createEmptyMovieClip( 
				"_smcSound" + _aSoundList.length, 
				_mcMusicContainer.getNextHighestDepth()
			);
			_aExternalMusicList.push( pSoundClip );
		}else{
			mcSoundTarget = _mcSoundContainer.createEmptyMovieClip( 
				"_smcSound" + _aSoundList.length, 
				_mcSoundContainer.getNextHighestDepth()
			);
			_aExternalSoundList.push( pSoundClip );
		}

		pSoundClip.attachExternalSound( sLinkageID, mcSoundTarget, sURL, bMusic, nVolume);
		
		this[sLinkageID] = Delegate.create(this, playSoundList); // Damian: changed new function(), by a delegate
		
		_aSoundList.push( pSoundClip );
		
		return ( _aSoundList.length - 1 );		
	}
	
	function playSoundList() {  // Added by Damian
		playSound(_aSoundList.length);
	}
	
	function attachSoundInLibrary( sLinkageID:String, bMusic:Boolean , nVolume):Number
	{
		// Let's check to see if the sound we're trying to attach has already been attached and
		// if so, we'll just return the existing sound ID.
		var nExistingSoundID:Number = getSoundID( sLinkageID );
		if ( nExistingSoundID != null ) 
		{
			return nExistingSoundID;
		}

		// Since we didn't find the sound to exist already - we'll create it
		
		var mcSoundTarget:MovieClip // Damian: Declaration moved here.
		
		
		if(bMusic){
			mcSoundTarget = _mcMusicContainer.createEmptyMovieClip( 
				"_smcSound" + _aSoundList.length, 
				_mcMusicContainer.getNextHighestDepth()
			);
		}else{
			mcSoundTarget = _mcSoundContainer.createEmptyMovieClip( 
				"_smcSound" + _aSoundList.length, 
				_mcSoundContainer.getNextHighestDepth()
			);
		}

		var pSoundClip:SoundClip = new SoundClip(this);
		pSoundClip.attachSoundInLibrary( sLinkageID, mcSoundTarget, bMusic, nVolume);
		
		this[sLinkageID] = Delegate.create(this, playSoundList); // Damian: changed new function(), by a delegate
		
		_aSoundList.push( pSoundClip );
		
		return ( _aSoundList.length - 1 );		
	}
	
	function getSoundID( sLinkageID:String ):Number
	{
		for ( var i:Number = 0; i < _aSoundList.length; ++i )
		{
			if ( sLinkageID == _aSoundList[ i ].getSoundName() )
			{
				return i;
			}
		}
		
		return null;
	}
	
	function getSoundInstance( sLinkageID:String ):SoundClip
	{
		for ( var i:Number = 0; i < _aSoundList.length; ++i )
		{
			if ( sLinkageID == _aSoundList[ i ].getSoundName() )
			{
				return _aSoundList[ i ];
			}
		}
		
		return null;
	}
	
	function playSound( nSoundIndex:Number )
	{
		_aSoundList[ nSoundIndex ].playSound();
	}
	
	function playSoundName(soundName_s:String){
		playSound(getSoundID( soundName_s ));
	}
	
	function pauseSound( nSoundIndex:Number )
	{
		_aSoundList[ nSoundIndex ].pauseSound();
	}
	
	function stopSound( nSoundIndex:Number )
	{
		
		_aSoundList[ nSoundIndex ].stopSound();
	}
	
	function setVolume( nSoundIndex:Number, nVolume:Number )
	{
		_aSoundList[ nSoundIndex ].setVol( nVolume );
	}
	
	function toggleSoundOn(){
		
		if(_bSoundOn){
			turnSoundOff()
		}
		else {
			turnSoundOn()
		}
		_cSharedObjectManager.saveData("bSoundOn",_bSoundOn)
	}
	
	function turnSoundOff(){
		_cEventManager.broadcastMessage( "TURN_SOUND_OFF" );
		var oSoundLeft:Object = { ll: 0, lr: 0, rr: 0, rl: 0};
		for(var count = 0;count< _aExternalSoundList.length;count++){
			_aExternalSoundList[count]._snSound.setTransform(oSoundLeft);
		}
		_snGlobalSound.setVolume(0);
		_bSoundOn = false;
	}
	
	function turnSoundOn(){
		_cEventManager.broadcastMessage( "TURN_SOUND_ON" );
		
		var oSoundLeft:Object = { ll: 100, lr: 0, rr: 100, rl: 0};
		for(var count = 0;count< _aExternalSoundList.length;count++){
			_aExternalSoundList[count]._snSound.setTransform(oSoundLeft);
		}
		_snGlobalSound.setVolume(100);
		_bSoundOn = true
	}
	
	function getSoundState():Boolean{
		return(_bSoundOn);
	}
	
	
	
	function toggleMusicOn(){
		if(_bMusicOn){
			turnMusicOff();
		}
		else {
			turnMusicOn();
		}
		_cSharedObjectManager.saveData("bMusicOn",_bMusicOn)
	}
	
	function turnMusicOff(){
		_cEventManager.broadcastMessage( "TURN_MUSIC_OFF" );
		var oSoundLeft:Object = { ll: 0, lr: 0, rr: 0, rl: 0};
		for(var count = 0;count< _aExternalSoundList.length;count++){
			_aExternalMusicList[count]._snSound.setTransform(oSoundLeft);
		}
			_snGlobalMusic.setVolume(0);
			_bMusicOn = false
	}
	
	function turnMusicOn(){
		_cEventManager.broadcastMessage( "TURN_MUSIC_ON" );
		var oSoundLeft:Object = { ll: 100, lr: 0, rr: 100, rl: 0};
		for(var count = 0;count< _aExternalSoundList.length;count++){
			_aExternalMusicList[count]._snSound.setTransform(oSoundLeft);
		}
		_snGlobalMusic.setVolume(100);
		_bMusicOn = true
	}
	
	function getMusicState():Boolean{
		return(_bMusicOn)
	}
	
	
	
	
	
}